import { useEffect, useRef, useMemo, useState } from "react";
import styles from './index.less';
import { getSudoku } from 'sudoku-gen';
import { Segmented, message } from 'antd';
import useSound from 'use-sound';
import SuccessView from "./components/SuccessView";
import { formatSecondsToHMS } from "@/utils/common";
import { isRandom30P } from './utils/util';
import Unit from "./components/Unit";
import { CHECK_CONFIG } from './utils/helper';
import SudokuStore, { DIFFICULTY_OPTIONS } from "./stores/SudokuStore";
import { observer, useLocalObservable } from 'mobx-react';
import { cloneDeep } from "lodash";
import { Modal } from 'antd';
import { history } from 'umi';

export default observer(() => {
    const store = useLocalObservable(() => new SudokuStore());
    const {
        audioUrl,
        difficulty,
        origin,
        puzzle,
        solution,
        mark,
        success,
        gameTime,
        errorItems,
        checkTimes,
    } = store;

    // 播放音乐
    const [playBg, { stop: stopBg }] = useSound(audioUrl, { loop: true });

    // 计时器
    const timerInterval = useRef<NodeJS.Timeout>();

    const [showModal, setShowModal] = useState(false);
    const [nextPath, setNextPath] = useState('');

    useEffect(() => {
        // 设置路由拦截
        const unblock = history.block(({ location }) => {
            // 拦截返回操作（POP 表示后退或前进）
            if (history.action == "POP") {
                setNextPath(location.pathname); // 保存目标路径
                setShowModal(true); // 显示弹窗
                return false; // 阻止默认跳转
            }
            return true; // 其他操作（如 PUSH）不拦截
        });

        return () => unblock(); // 组件卸载时解除拦截
    }, []);

    // 用户确认离开
    const handleConfirm = () => {
        console.log(`## 用户确认离开 nextPath=${nextPath}`);
        history.push(nextPath); // 手动跳转到目标页
        setShowModal(false);
    };

    // 用户取消离开
    const handleCancel = () => {
        setShowModal(false);
    };

    useEffect(() => {
        // 每次puzzle变化，都检查一次是否完成
        const curr = puzzle.join('');
        if (!!curr && !!solution && curr === solution) {
            store.setSuccess(true);
            if (timerInterval.current) {
                clearInterval(timerInterval.current);
                timerInterval.current = undefined;
            }
        }
    }, [puzzle]);

    // 是否游戏中
    const isGaming = useMemo(() => !!timerInterval.current, [timerInterval.current]);

    const startGame = () => {
        playBg();
        const sudoku = getSudoku(difficulty == 'begin' ? 'easy' : difficulty);
        const { puzzle, solution: s } = sudoku;

        const pArray = puzzle.split('').map((i, index: number) => {
            if (i == '-') {
                if (difficulty == 'begin' && isRandom30P()) {
                    return parseInt(s[index]);
                }
                return 0;
            }
            return parseInt(i);
        });
        store.setOrigin(pArray);
        store.setPuzzle(pArray);
        store.setMark([]);
        store.setSolution(s);
        store.setSuccess(false);
        store.setStartTime(new Date().getTime());
        startTimer();
    }

    const endGame = () => {
        stopBg();
        store.setOrigin(null);
        store.setPuzzle(null);
        store.setMark([]);
        store.setSolution('');
        store.setSuccess(false);
        store.setGameTime('');
        endTimer();
    }

    const startTimer = () => {
        if (timerInterval.current) {
            clearInterval(timerInterval.current);
        }
        timerInterval.current = setInterval(() => {
            const newTime = new Date().getTime();
            const seconds = (newTime - store.startTime) / 1000;
            const hms = formatSecondsToHMS(seconds);
            store.setGameTime(hms);
        }, 1000);
    }

    const endTimer = () => {
        clearInterval(timerInterval.current);
        timerInterval.current = undefined;
        store.setStartTime(0);
    }

    const onCheckClick = () => {
        if (!isGaming) {
            return;
        }
        if (checkTimes <= 0) {
            message.error('本局检查次数已用完');
            return;
        }
        store.setCheckTimes(checkTimes - 1);
        const errorItem: number[] = [];
        for (let i = 0; i < puzzle.length; i++) {
            const solutionArray = solution.split('').map(i => {
                if (i == '-') {
                    return 0;
                }
                return parseInt(i);
            });;
            const pi = puzzle[i];
            const si = solutionArray[i];
            if (pi != 0 && si != 0 && pi != si) {
                errorItem.push(i);
            }
        }
        if (!errorItem?.length) {
            message.info('没有发现错误');
        } else {
            message.error(`发现${errorItem.length}处错误`);
            store.setErrorItems(errorItem);
            setTimeout(() => {
                store.setErrorItems([]);
            }, 5000);
        }
    }

    const onSettingClick = () => {
        if (isGaming) {
            return;
        }
    }

    const onDifficultyChange = (value: string) => {
        store.setCheckTimes(CHECK_CONFIG[value as Difficulty | 'begin']);
        store.setDifficulty(value as Difficulty);
    }

    const onNumberSelect = (index: number, number: number) => {
        const copy = [...puzzle];
        copy[index] = number;
        store.setPuzzle(copy);
        if (number) {
            const copyMark = cloneDeep(mark);
            copyMark[index] = [];
            store.setMark(copyMark);
        }
    }

    const onMarkSelect = (index: number, number: number[]) => {
        const copy = cloneDeep(mark);
        copy[index] = number;
        store.setMark(copy);
    }

    return (
        <div className={styles.container}>
            <div className={styles.header}>
                <div className={isGaming ? styles.stopButton : styles.startButton} onClick={isGaming ? endGame : startGame}>
                    {isGaming ? '结束' : '开始'}
                </div>

                <div className={styles.buttonLayout}>
                    <div className={isGaming ? styles.check : styles.disableButton} onClick={onCheckClick}>检查({checkTimes})次</div>
                    <div className={isGaming ? styles.disableButton : styles.setting} style={{ marginTop: 10 }} onClick={onSettingClick}>设置</div>
                </div>

                <div className={styles.timeLayout}>
                    <span className={styles.time}>{gameTime || '00:00:00'}</span>

                    <Segmented<string>
                        options={DIFFICULTY_OPTIONS}
                        style={{ width: 254 }}
                        value={difficulty}
                        onChange={onDifficultyChange}
                        disabled={isGaming}
                    />
                </div>
            </div>

            <div className={styles.main}>
                {puzzle?.map((i, index) => {
                    return (
                        <Unit
                            key={`${i}-${index}`}
                            index={index}
                            isInit={puzzle[index] == -1}
                            isStable={origin[index] > 0}
                            num={puzzle[index]}
                            mark={mark[index]}
                            onNumberSelect={onNumberSelect}
                            onMarkSelect={onMarkSelect}
                            isError={errorItems?.includes(index)}
                        />
                    );
                })}

                <SuccessView
                    success={success}
                    difficulty={difficulty}
                    gameTime={gameTime}
                />
            </div>

            <Modal
                width={300}
                open={showModal}
                title="确认退出本局？"
                onOk={handleConfirm}
                onCancel={handleCancel}
                okText="确认"
                cancelText="取消"
            />
        </div>
    );
});
